using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace OdsController {
	
	

	public class Win32Helper {
		
		public const int WM_QUERYENDSESSION = 0x11;
		public const int IDANI_CAPTION = 3;
		public const int SW_HIDE = 0;
		public const int SW_MAX = 10;
		public const int SW_MAXIMIZE = 3;
		public const int SW_MINIMIZE = 6;
		public const int SW_NORMAL = 1;
		public const int SW_RESTORE = 9;
		public const int SW_SHOW = 5;
		public const int SW_SHOWDEFAULT = 10;
		public const int SW_SHOWMAXIMIZED = 3;
		public const int SW_SHOWMINIMIZED = 2;
		public const int SW_SHOWMINNOACTIVE = 7;
		public const int SW_SHOWNA = 8;
		public const int SW_SHOWNOACTIVATE = 4;
		public const int SW_SHOWNORMAL = 1;
		public const int WPF_RESTORETOMAXIMIZED = 2;

		[StructLayout(LayoutKind.Sequential)]
		public class ManagedPt {
			public int x = 0;
			public int y = 0;

			public ManagedPt() {
			}

			public ManagedPt(int x, int y) {
				this.x = x;
				this.y = y;
			}
		}

		/// &ltsummary>
		/// Rect struct used for GetWindowPlacement API.
		/// </summary>
		[StructLayout(LayoutKind.Sequential)]
		public class ManagedRect {
			public int x = 0;
			public int y = 0;
			public int right = 0;
			public int bottom = 0;

			public ManagedRect() {
			}

			public ManagedRect(int x, int y, int right, int bottom) {
				this.x = x;
				this.y = y;
				this.right = right;
				this.bottom = bottom;
			}
		}

		/// &ltsummary>
		/// WindowPlacement struct used for GetWindowPlacement API.
		/// </summary>
		[StructLayout(LayoutKind.Sequential)]
		public class ManagedWindowPlacement {
			public uint length = 0;
			public uint flags = 0;
			public uint showCmd = 0;
			public ManagedPt minPosition = null;
			public ManagedPt maxPosition = null;
			public ManagedRect normalPosition = null;

			public ManagedWindowPlacement() {
				this.length = (uint)Marshal.SizeOf(this);
			}
		}
		
		[StructLayout(LayoutKind.Sequential)]
		public struct RECT {
			public int left;
			public int top;
			public int right;
			public int bottom;
			public override string ToString() {
				return ("Left :" + left.ToString() + "," + "Top :" + top.ToString() + "," + "Right :" + right.ToString() + "," + "Bottom :" + bottom.ToString());
			}
		}
	
		#region P/Invokes
		[DllImport("User32.dll")]
		public static extern int ShowWindowAsync(IntPtr hWnd, int swCommand);

		[DllImport("USER32.DLL", SetLastError = true)]
		public static extern uint ShowWindow(uint hwnd, int showCommand);

		[DllImport("USER32.DLL", SetLastError = true)]
		public static extern uint SetForegroundWindow(IntPtr hwnd);

		[DllImport("USER32.DLL", SetLastError = true)]
		public static extern uint GetWindowPlacement(IntPtr hwnd,
				[In, Out]ManagedWindowPlacement lpwndpl);

		[DllImport("USER32.DLL", SetLastError = true)]
		public static extern uint FindWindow(string lpClassName, string lpWindowName);

		[DllImport("User32.dll", EntryPoint = "ShowWindow", CharSet = CharSet.Auto)]
		public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

		[DllImport("User32.dll", EntryPoint = "UpdateWindow", CharSet = CharSet.Auto)]
		public static extern bool UpdateWindow(IntPtr hWnd);

		[DllImport("user32.dll", EntryPoint = "IsIconic", CharSet = CharSet.Auto)]
		public static extern bool IsIconic(IntPtr hWnd);

		[DllImport("user32.dll", EntryPoint = "FindWindowEx", CharSet = CharSet.Auto)]
		public extern static IntPtr FindWindowEx(
			IntPtr hwndParent,
			IntPtr hwndChildAfter,
			[MarshalAs(UnmanagedType.LPTStr)]
			string lpszClass,
			[MarshalAs(UnmanagedType.LPTStr)]
			string lpszWindow);

		[DllImport("user32.dll", EntryPoint = "DrawAnimatedRects", CharSet = CharSet.Auto)]
		public static extern bool DrawAnimatedRects(IntPtr hwnd, int idAni, ref RECT lprcFrom, ref RECT lprcTo);

		[DllImport("user32.dll", EntryPoint = "GetWindowRect", CharSet = CharSet.Auto)]
		public extern static bool GetWindowRect(IntPtr hwnd, ref RECT lpRect);

		#endregion P/Invokes	
	
		public static IntPtr GetNotificationAreaHandle() {
			IntPtr hwnd = FindWindowEx(IntPtr.Zero, IntPtr.Zero, "Shell_TrayWnd", null);
			Console.WriteLine("Shell_TrayWnd" + hwnd.ToString());
			hwnd = FindWindowEx(hwnd, IntPtr.Zero, "TrayNotifyWnd", null);
			Console.WriteLine("TrayNotifyWnd" + hwnd.ToString());
			hwnd = FindWindowEx(hwnd, IntPtr.Zero, "SysPager", null);
			Console.WriteLine("SysPager" + hwnd.ToString());

			if (hwnd != IntPtr.Zero)
				hwnd = FindWindowEx(hwnd, IntPtr.Zero, null, "Notification Area");

			Console.WriteLine("Notification Area" + hwnd.ToString());
			return hwnd;
		}
	
		static public void ActivateWindow(IntPtr hwndInstance) {

			// Then, get the WindowPlacement, so we can decide the best way to 
			// activate the window correctly.
			ManagedWindowPlacement placement = new ManagedWindowPlacement();
			GetWindowPlacement(hwndInstance, placement);

			ShowWindow(hwndInstance, SW_SHOWNORMAL);
			SetForegroundWindow(hwndInstance);

			//if (placement.showCmd == SW_SHOWMINIMIZED) {
			//  // if the window is minimized, then we need to restore it to its
			//  // previous size.  we also take into account whether it was 
			//  // previously maximized.
			//  int showCmd = SW_SHOWNORMAL;
			//  ShowWindow(hwndInstance, showCmd);
			//} else {
			//  // if it's not minimized, then we just call SetForegroundWindow to 
			//  // bring it to the front.
			//  SetForegroundWindow(hwndInstance);
			//}
		}

	}

}


//public sealed class MemoryMappedFile : IDisposable {
	//  private const int FILE_MAP_WRITE = 0x2;
	//  private const int FILE_MAP_READ = 0x0004;


	//  [DllImport("kernel32.dll", EntryPoint = "OpenFileMapping", SetLastError = true, CharSet = CharSet.Auto)]
	//  private static extern IntPtr OpenFileMapping(int dwDesiredAccess, bool bInheritHandle, String lpName);

	//  [DllImport("Kernel32.dll", EntryPoint = "CreateFileMapping", SetLastError = true, CharSet = CharSet.Auto)]
	//  private static extern IntPtr CreateFileMapping(uint hFile, IntPtr lpAttributes, uint flProtect, uint dwMaximumSizeHigh, uint dwMaximumSizeLow, string lpName);

	//  [DllImport("Kernel32.dll")]
	//  private static extern IntPtr MapViewOfFile(IntPtr hFileMappingObject, uint dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, uint dwNumberOfBytesToMap);

	//  [DllImport("Kernel32.dll", EntryPoint = "UnmapViewOfFile", SetLastError = true, CharSet = CharSet.Auto)]
	//  private static extern bool UnmapViewOfFile(IntPtr lpBaseAddress);

	//  [DllImport("kernel32.dll", EntryPoint = "CloseHandle", SetLastError = true, CharSet = CharSet.Auto)]
	//  private static extern bool CloseHandle(uint hHandle);

	//  [DllImport("kernel32.dll", EntryPoint = "GetLastError", SetLastError = true, CharSet = CharSet.Auto)]
	//  private static extern uint GetLastError();

	//  private IntPtr memoryFileHandle;

	//  public enum FileAccess : int {
	//    ReadOnly = 2,
	//    ReadWrite = 4
	//  }

	//  private MemoryMappedFile(IntPtr memoryFileHandle) {
	//    this.memoryFileHandle = memoryFileHandle;
	//  }


	//  public static MemoryMappedFile CreateMMF(string fileName, FileAccess access, int size) {
	//    if (size < 0)
	//      throw new ArgumentException("The size parameter should be a number greater than Zero.");

	//    IntPtr memoryFileHandle = CreateFileMapping(0xFFFFFFFF, IntPtr.Zero, (uint)access, 0, (uint)size, fileName);
	//    if (memoryFileHandle == IntPtr.Zero)
	//      throw new SharedMemoryException("Creating Shared Memory failed.");

	//    return new MemoryMappedFile(memoryFileHandle);
	//  }



	//  public static IntPtr ReadHandle(string fileName) {
	//    IntPtr mappedFileHandle = OpenFileMapping((int)FileAccess.ReadWrite, false, fileName);
	//    if (mappedFileHandle == IntPtr.Zero)
	//      throw new SharedMemoryException("Opening the Shared Memory for Read failed.");

	//    IntPtr mappedViewHandle = MapViewOfFile(mappedFileHandle, (uint)FILE_MAP_READ, 0, 0, 8);
	//    if (mappedViewHandle == IntPtr.Zero)
	//      throw new SharedMemoryException("Creating a view of Shared Memory failed.");

	//    IntPtr windowHandle = Marshal.ReadIntPtr(mappedViewHandle);
	//    if (windowHandle == IntPtr.Zero)
	//      throw new ArgumentException("Reading from the specified address in  Shared Memory failed.");

	//    UnmapViewOfFile(mappedViewHandle);
	//    CloseHandle((uint)mappedFileHandle);
	//    return windowHandle;
	//  }


	//  public void WriteHandle(IntPtr windowHandle) {
	//    IntPtr mappedViewHandle = MapViewOfFile(memoryFileHandle, (uint)FILE_MAP_WRITE, 0, 0, 8);
	//    if (mappedViewHandle == IntPtr.Zero)
	//      throw new SharedMemoryException("Creating a view of Shared Memory failed.");

	//    Marshal.WriteIntPtr(mappedViewHandle, windowHandle);

	//    UnmapViewOfFile(mappedViewHandle);
	//    CloseHandle((uint)mappedViewHandle);
	//  }


	//  #region IDisposable Member
	//  public void Dispose() {
	//    if (memoryFileHandle != IntPtr.Zero) {
	//      if (CloseHandle((uint)memoryFileHandle))
	//        memoryFileHandle = IntPtr.Zero;
	//    }
	//  }

	//  #endregion
	//}

	//[Serializable]
	//public class SharedMemoryException : ApplicationException {
	//  public SharedMemoryException() {

	//  }
	//  public SharedMemoryException(string message)
	//    : base(message) {
	//  }
	//  public SharedMemoryException(string message, Exception inner)
	//    : base(message, inner) {
	//  }

	//}